package cn.echoparrot.domain.entity;

import org.springframework.util.Assert;

/**
 * 聊天记忆设置
 * @param messageLimit 整个窗口达到阈值时，按批次摘要，按批次缩减。
 * @param tokenLimit 达到tokenLimit 时需要先写入库，再缩减窗口消息并将缩减的部分进行摘要。
 * @param batchSize 新消息达到批次时刷写到库，TODO 批次写入 与 批次摘要，可以是两个值，本质不关联。
 * @param batchSeconds
 */
public record MemorySettings(int messageLimit, int tokenLimit,
                             int batchSize, int batchSeconds) {
    public MemorySettings {
        Assert.isTrue(messageLimit > 0, "messageLimit must be greater than 0");
        Assert.isTrue(tokenLimit > 0, "tokenLimit must be greater than 0");
        Assert.isTrue(batchSize > 0, "batchSize must be greater than 0");
        Assert.isTrue(batchSeconds > 0, "batchSeconds must be greater than 0");
        Assert.isTrue(batchSize<= messageLimit, "batchSize must be less than or equal to messageLimit");
    }

    public static final MemorySettings DEFAULT = new MemorySettings(20, 6000, 12, 60);

    public static class Builder {

        private int messageLimit = DEFAULT.messageLimit();
        private int tokenLimit = DEFAULT.tokenLimit();
        private int batchSize = DEFAULT.batchSize();
        private int batchSeconds = DEFAULT.batchSeconds();

        /**
         * 设置大模型上下文对话历史记录的条数限制
         *
         * @param messageLimit
         * @return
         */
        public Builder messageLimit(int messageLimit) {
            this.messageLimit = messageLimit;
            return this;
        }

        /**
         * 模型上下文对话历史记录的字符数限制
         *
         * @param tokenLimit
         * @return
         */
        public Builder tokenLimit(int tokenLimit) {
            this.tokenLimit = tokenLimit;
            return this;
        }

        /**
         * 当对话历史记录达到批量输出的预设条数时，将批量入库
         *
         * @param batchSize
         * @return
         */
        public Builder batchSize(int batchSize) {
            this.batchSize = batchSize;
            return this;
        }

        /**
         * 当对话历史记录达到批量输出的预设时间时，将批量入库
         *
         * @param batchSeconds
         * @return
         */
        public Builder batchSeconds(int batchSeconds) {
            this.batchSeconds = batchSeconds;
            return this;
        }
        public MemorySettings build() {
            return new MemorySettings(messageLimit, tokenLimit,
                    batchSize, batchSeconds);
        }

    }

    public Builder builder() {
        return new Builder();
    }
}
